<template>
  <div
    class="zc-input-number"
    :class="{
      'is-disabled': inputNumberDisabled
    }"
  >
    <span
      role="button"
      :class="{ 'is-disabled': minDisabled || inputNumberDisabled }"
      v-repeat-click="decrease"
      @keydown.enter="decrease"
      class="zc-input-number__decrease"
      >-</span
    >
    <span
      role="button"
      :class="{ 'is-disabled': maxDisabled || inputNumberDisabled }"
      v-repeat-click="increase"
      @keydown.enter="increase"
      class="zc-input-number__increase"
      >+</span
    >
    <zc-input
      autoFoucs
      type="number"
      ref="input"
      :disabled="inputNumberDisabled"
      :min="min"
      :max="max"
      @change="handleChange"
      @keydown.up.native.prevent="increase"
      @keydown.down.native.prevent="decrease"
      :value="dispalyValue"
      style="caret-color: #000"
      onkeypress="return(/[\d]/.test(String.fromCharCode(event.keyCode)))"
    ></zc-input>
  </div>
</template>

<script>
import RepeatClick from "../directives/repeat-click";

export default {
  name: "ZcInputNumber",
  data() {
    return {
      currentValue: 0
    };
  },
  directives: {
    repeatClick: RepeatClick
  },
  props: {
    value: [String, Number],
    min: {
      type: Number,
      default: -Infinity
    },
    max: {
      type: Number,
      default: Infinity
    },
    disabled: {
      type: Boolean,
      default: false
    },
    step: {
      type: Number,
      default: 1
    },
    precision: {
      type: Number,
      default: 2
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(value) {
        this.currentValue = value;
      }
    }
  },
  computed: {
    dispalyValue() {
      let currentValue = this.currentValue;
      if (typeof currentValue === "number") {
        if (this.precision !== undefined) {
          currentValue = currentValue.toFixed(this.precision);
        }
      }

      return currentValue;
    },
    minDisabled() {
      return this._decrease(this.value, this.step) < this.min;
    },
    maxDisabled() {
      return this._increase(this.value, this.step) > this.max;
    },
    inputNumberDisabled() {
      return this.disabled;
    }
  },
  methods: {
    handleChange(value) {
      const numValue = value === "" ? undefined : Number(value);
      if (value > this.max || value < this.min) return;
      this.setCurrentValue(numValue);
    },
    toPrecision(num, precision) {
      // if (precision === undefined) precision = this.numPrecision;
      return parseFloat(
        Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision)
      );
    },
    _increase(val, step) {
      if (typeof val !== "number" && val !== undefined) {
        return this.currentValue;
      }
      return this.toPrecision(val + step, this.precision);
    },
    _decrease(val, step) {
      if (typeof val !== "number" && val !== undefined) {
        return this.currentValue;
      }

      return this.toPrecision(val - step, this.precision);
    },
    decrease: function () {
      if (this.inputNumberDisable || this.minDisabled) return;

      const value = this.value || 0;
      const newVal = this._decrease(value, this.step);
      this.setCurrentValue(newVal);
    },
    increase() {
      if (this.inputNumberDisable || this.maxDisabled) return;

      const value = this.value || 0;
      const newVal = this._increase(value, this.step);
      this.setCurrentValue(newVal);
    },
    setCurrentValue(newVal) {
      this.$emit("input", newVal);
      this.$emit("change", newVal);
      this.currentValue = newVal;
    }
  }
};
</script>

<style lang="scss">
.zc-input-number {
  display: inline-block;
  position: relative;
  line-height: 38px;
  .is-disabled {
    cursor: not-allowed;
    color: #dcdfe6;
  }
  .el-input_inner {
    -webkit-appearance: none;
    padding-left: 50px;
    padding-right: 50px;
    text-align: center;
    caret-color: auto;
  }
}

.zc-input-number__decrease,
.zc-input-number__increase {
  position: absolute;
  z-index: 1;
  top: 1px;
  width: 40px;
  height: auto;
  text-align: center;
  background: #f5f7fa;
  color: #606266;
  cursor: pointer;
  font-size: 13px;
  -moz-user-select: none;
  /*火狐*/
  -webkit-user-select: none;
  /*webkit浏览器*/
  -ms-user-select: none;
  /*IE10*/
  -khtml-user-select: none;
  /*早期浏览器*/
  user-select: none;
}

.zc-input-number__decrease {
  left: 1px !important;
  border-radius: 4px 0 0 4px;
  border-right: 1px solid #dcdfe6;
}

.zc-input-number__increase {
  right: 1px !important;
  border-radius: 0 4px 4px 0;
  border-left: 1px solid #dcdfe6;
}
</style>
